from typing import List, Dict, Any
from fastapi import Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_
from sqlalchemy.exc import NoResultFound

from basic.models import (
    LogicalEntry,
)
from basic.database import get_db
from service.interfaces import IEntryService
from service.repository.entryRepository import (
    get_parent_path, 
    check_exist_same_path, 
    check_parent_exist, 
    create_new_entry,
    delete_entry,
    get_children_entries,
    move_entry
)


class EntryService(IEntryService):
    def __init__(self, db: AsyncSession = Depends(get_db)):
        self.db = db

    async def create_entry(self, repo_key: str, entry_path: str, is_dir: bool) -> Dict[str, Any]:
        try:
            # 首先检查是否已存在相同路径的条目
            existing_entry = await check_exist_same_path(self.db, entry_path, repo_key)
            
            if existing_entry:
                # 如果已存在相同路径的条目，直接返回
                print(f"Entry with path {entry_path} already exists, returning existing entry")
                return {
                    "entryKey": existing_entry.key,
                    "path": existing_entry.path,
                    "isDir": existing_entry.is_directory
                }
                
            parent_exist, parent_id = await check_parent_exist(self.db, entry_path, repo_key)
            if not parent_exist:
                raise HTTPException(status_code=400, detail="Parent directory does not exist")

            # 创建新条目
            new_entry = await create_new_entry(self.db, entry_path, is_dir, parent_id, repo_key)
           
            # 提交事务
            await self.db.commit()
            
            # 返回字典
            return {
                "entryKey": new_entry.key,
                "path": new_entry.path,
                "isDir": new_entry.is_directory
            }

        except Exception as e:
            # 回滚事务
            await self.db.rollback()
            # 记录其他异常并抛出友好错误
            print(f"Error creating entry: {e}")
            raise e

    async def delete_entry(self, key: str) -> Dict[str, str]:
        try:
            async with self.db.begin():
                # 删除条目
                result = await delete_entry(self.db, key)
                if not result:
                    raise HTTPException(status_code=404, detail="Entry not found")
                
                await self.db.commit()
                
            return {"entryKey": key}
            
        except Exception as e:
            await self.db.rollback()
            print(f"Error deleting entry: {e}")
            raise HTTPException(status_code=500, detail=f"Failed to delete entry: {str(e)}")

    async def get_entry_children(self, entry_key: str):
        try:
            # 获取子条目
            entries = await get_children_entries(self.db, entry_key)
            return entries
            
        except Exception as e:
            print(f"Error getting children entries: {e}")
            raise e

    async def update_entry(self, repo_key: str, entry_key: str, update_key: str, update_value: str):
        try:
            match update_key:
                case "path":
                    async with self.db.begin():
                        # 更新条目
                        updated_entry = await move_entry(self.db, entry_key, update_value)
                        await self.db.commit()
                        
                    return {"entry_key": updated_entry.key}                   
                case _:
                    raise HTTPException(status_code=400, detail="Invalid update key")
        except Exception as e:
            await self.db.rollback()
            print(f"Error updating entry: {e}")
            raise HTTPException(status_code=500, detail=f"Failed to update entry: {str(e)}")
